import React, { useEffect, useState } from 'react'
import {
  Card,
  Row,
  Col,
  Tree,
  Tag,
  Pagination,
  Table,
  Button,
  Spin,
} from 'antd'
import { useParams } from 'react-router-dom'
//Tree组件的ts类型
import type { DataNode, TreeProps } from 'antd/es/tree'
import type { ColumnsType } from 'antd/es/table'
import {
  IdepList,
  IscheduleList,
  IscheduleDetailList,
  IscheduleDetail,
} from '@api/hospitalList/model/hospitalListTypes'

import {
  reqGetDepList,
  reqGetScheduleRules,
  reqGetScheduleDetail,
} from '@api/hospitalList'

let depcode: string // 用于存储科室编码的变量
export default function HospitalSchedule() {
  // 获取当前医院的医院编码
  const hoscode = useParams().hoscode as string
  // 存储所有科室数据的状态
  const [depList, setDepList] = useState<IdepList>([])

  // 存储所有一级科室编码的状态
  const [depCodes, setDepCodes] = useState<string[]>([])

  // 存储排班规则数据的状态
  const [scheduleRules, setScheduleRules] = useState<IscheduleList>([])

  // 面包屑相关的三个状态
  const [hosname, setHosname] = useState('')
  const [depname, setDepname] = useState('')
  const [workDate, setWorkDate] = useState('')

  // 分页的状态
  const [total, setTotal] = useState(0)
  const [pageSize, setPageSize] = useState(5)
  const [page, setPage] = useState(1)

  // 存储排班详情数据的状态
  const [detail, setDetail] = useState<IscheduleDetailList>([])

  // 正在加载的状态
  const [bloading, setBloading] = useState(false)
  const [dloading, setDloading] = useState(false)
  const [sloading, setSloading] = useState(false)
  const [xloading, setXloading] = useState(false)

  // 组件挂载的时候获取所有科室数据
  useEffect(() => {
    setBloading(true)
    setDloading(true)
    setSloading(true)
    setXloading(true)
    ;(async function () {
      let result = await reqGetDepList(hoscode)
      // 让所有的一级科室禁用
      result = result.map((item) => {
        item.disabled = true
        return item
      })
      setDepList(result)

      // 收集所有一级科室的depcode,然后存储到状态中
      const depcodes = result.map((item) => {
        return item.depcode
      })
      setDepCodes(depcodes)

      // 当所有的科室数据获取完毕之后,然后获取第一个一级科室中的第一个二级科室的排班规则数据
      depcode = result[0].children[0].depcode
      getScheduleRules(1, 5, depcode)

      // 默认将第一个一级科室的第一个二级科室的depname存储到状态中并渲染
      setDepname(result[0].children[0].depname)

      // 隐藏获取科室数据的loading
      setDloading(false)
    })()
  }, [])

  // 获取排班规则数据的函数
  async function getScheduleRules(
    page: number,
    pageSize: number,
    depcode: string
  ) {
    const result = await reqGetScheduleRules(page, pageSize, hoscode, depcode)
    // console.log(result)
    // 将排班规则数据存储到状态中,并渲染
    setScheduleRules(result.bookingScheduleList)

    //设置total
    setTotal(result.total)
    // 设置医院名称
    setHosname(result.baseMap.hosname)
    // 设置面包屑的workDate
    const workDate = result.bookingScheduleList[0].workDate
    setWorkDate(workDate)

    // 获取排班详情数据并渲染
    getScheduleDetail(workDate)

    // 隐藏面包屑的loading
    setBloading(false)
    // 隐藏排班规则的loading
    setSloading(false)
  }

  // 获取排班详情数据的函数
  async function getScheduleDetail(workDate: string) {
    // 注意: 虽然状态中有workDate.但是修改状态是异步的.所以还是应该将workDate最新数据传入到当前函数中
    const result = await reqGetScheduleDetail(hoscode, depcode, workDate)
    setDetail(result)
    // 隐藏排班详情的loading
    setXloading(false)
  }

  // 当用户选中的Tree组件中的某个节点触发的事件处理函数
  const onSelect: TreeProps['onSelect'] = (selectedKeys, info) => {
    console.log('selected', selectedKeys, info)
  }

  const columns: ColumnsType<IscheduleDetail> = [
    {
      title: '序号',
      render(a, b, index) {
        return index + 1
      },
    },
    {
      title: '职称',
      dataIndex: 'title',
    },
    {
      title: '号源时间',
      dataIndex: 'workDate',
    },
    {
      title: '可预约数',
      dataIndex: 'availableNumber',
    },
    {
      title: '剩余预约数',
      dataIndex: 'reservedNumber',
    },
    {
      title: '挂号费(元)',
      dataIndex: 'amount',
    },
    {
      title: '擅长技能',
      dataIndex: 'skill',
    },
  ]
  return (
    <Card>
      {bloading ? (
        <Spin></Spin>
      ) : (
        <p>
          选择：{hosname} / {depname} / {workDate}
        </p>
      )}
      {/* gutter 设置一行中列的间隔 20的单位是px */}
      <Row gutter={20}>
        <Col
          span={4}
          style={{ border: '1px solid #ccc', height: 400, overflow: 'auto' }}
        >
          {dloading ? (
            <Spin />
          ) : (
            <Tree
              // checkable //是否在tree组件中展示复选框
              // defaultExpandedKeys={depCodes} // 默认展开的节点的key值
              // 注意: defaultExpandedKeys 是默认的.只在第一次组件创建的时候生效
              expandedKeys={depCodes} // 让Tree组件节点展开的配置属性
              // defaultSelectedKeys={['0-0-0', '0-0-1']} // 默认选中的节点的key值
              // defaultCheckedKeys={['0-0-0', '0-0-1']} // 默认复选框被选中的节点的key值
              onSelect={onSelect} // 当用户点击了某个节点触发的事件
              // onCheck={onCheck} // 当用户点击了复选框的触发的事件
              // TreeData要求传入的数据类型是DataNode[],但是我们的数据是IdepList. 解决办法: 就是把我们的数据断言成any
              treeData={depList as any} // 当前Tree组件呈现的数据
              // 注意: Tree组件渲染数据时,默认找数据对象中的title作为节点的名称,找key作为节点的唯一标识,但是我们的数据是从服务器拿到的,没有title和key.所以使用fieldName告诉Tree组件,使用depcode去替换key.使用depname去替换title
              fieldNames={{
                key: 'depcode',
                title: 'depname',
              }}
            />
          )}
        </Col>
        <Col span={20}>
          {sloading ? (
            <Spin />
          ) : (
            <div>
              {scheduleRules.map((item, index) => {
                return (
                  <Tag
                    color={item.workDate === workDate ? 'green' : ''}
                    key={index}
                    onClick={() => {
                      // 修改面包屑中workDate的值
                      setWorkDate(item.workDate)
                      // 让排班详情的loading显示
                      setXloading(true)

                      // 获取排班详情数据
                      getScheduleDetail(item.workDate)
                    }}
                  >
                    <div>
                      {item.workDate} {item.dayOfWeek}
                    </div>
                    <div>
                      {item.availableNumber} / {item.reservedNumber}
                    </div>
                  </Tag>
                )
              })}
            </div>
          )}

          <Pagination
            style={{ marginTop: 10, marginBottom: 10 }}
            total={total}
            current={page}
            pageSize={pageSize}
            showSizeChanger={true}
            pageSizeOptions={[2, 5, 10]}
            onChange={(page, pageSize) => {
              setPage(page)
              setPageSize(pageSize)
              // 展示排班详情和排班规则的loading
              setSloading(true)
              setXloading(true)
              // 重新获取排班规则数据
              getScheduleRules(page, pageSize, depcode)
            }}
          ></Pagination>
          <Table
            rowKey={'id'}
            loading={xloading}
            columns={columns}
            dataSource={detail}
            pagination={false} //表格不显示分页器
          ></Table>
          <Button style={{ marginTop: 10 }}>返回</Button>
        </Col>
      </Row>
    </Card>
  )
}
